#!/usr/bin/env python3
# -*- coding:utf-8 -*-


"""
singleton
"""

import threading


class SingletonMeta(type):
    """
    单例
    """
    _instances = {}
    _lock = threading.Lock()

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            with cls._lock:
                if cls not in cls._instances:
                    instance = super(SingletonMeta, cls).__call__(*args, **kwargs)
                    cls._instances[cls] = instance
        return cls._instances[cls]


def singleton(cls):
    """ 单例模式(装饰器) """
    _instance = {}

    def _singleton(*args, **kwargs):
        """ _singleton """
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]

    return _singleton


class Singleton(object):
    """" 单例模式 """
    _instance_lock = threading.Lock()
    _instance_flag = False

    def __new__(cls, *args, **kwargs):
        """ __new__ """
        if not hasattr(Singleton, "_instances"):
            Singleton._instances = {}

        cls_name = cls.__name__
        instance = Singleton._instances.get(cls_name, None)
        if instance is not None:
            return instance

        with Singleton._instance_lock:
            instance = Singleton._instances.get(cls_name, None)
            if instance is not None:
                return instance

            instance = super().__new__(cls)
            Singleton._instances[cls_name] = instance
            return instance

    def __init__(self):
        """ __init__ """
        if not self._instance_flag:
            self._instance_flag = True
